package com.hcc.repository.gen.metadata;

import com.hcc.repository.core.jdbc.JdbcOperations;
import com.hcc.repository.core.jdbc.JdbcOperationsImpl;
import com.hcc.repository.core.jdbc.ResultMapper;
import com.hcc.repository.core.utils.CollUtils;
import com.hcc.repository.core.utils.ReflectUtils;
import com.hcc.repository.gen.config.GlobalConfig;
import com.hcc.repository.gen.constants.GenerateDateType;
import com.hcc.repository.gen.model.ColumnMetadata;
import com.hcc.repository.gen.model.TableMetadata;
import com.mysql.cj.MysqlType;

import javax.sql.DataSource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Date;
import java.util.List;

/**
 * AbstractMetadataQuery
 *
 * @author hushengjun
 * @date 2023/9/28
 */
public abstract class AbstractMetadataQuery implements MetadataQuery {
    private DataSource dataSource;
    private JdbcOperations jdbcOperations;

    @Override
    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
        this.jdbcOperations = new JdbcOperationsImpl(dataSource);
    }

    @Override
    public TableMetadata buildTableMetadata(String tableName, GlobalConfig globalConfig) {
        TableMetadata tableMetadata = jdbcOperations.queryForObject(queryTableMetadataSql(tableName), new Object[]{}, buildTableResultMapper());
        if (tableMetadata == null) {
            throw new IllegalArgumentException(String.format("表：[%s]未查询到元数据信息", tableName));
        }
        List<ColumnMetadata> columnMetadataList = jdbcOperations.queryForList(queryColumnMetadataSql(tableName), new Object[]{}, buildColumnResultMapper());
        if (CollUtils.isEmpty(columnMetadataList)) {
            throw new IllegalArgumentException(String.format("表：[%s]未查询到列元数据信息", tableName));
        }
        tableMetadata.setGlobalConfig(globalConfig);
        columnMetadataList.forEach(c -> {
            if (c.getJavaType() == null || Object.class.equals(c.getJavaType())) {
                c.setJavaType(this.getJavaType(c.getColumnType()));
            }
            this.changeJavaType(globalConfig, c);
        });
        tableMetadata.setColumns(columnMetadataList);

        return tableMetadata;
    }

    protected abstract String queryTableMetadataSql(String tableName);

    protected abstract String queryColumnMetadataSql(String tableName);

    protected abstract ResultMapper<TableMetadata> buildTableResultMapper();

    protected abstract ResultMapper<ColumnMetadata> buildColumnResultMapper();

    protected abstract Class<?> getJavaType(String jdbcType);

}
